<template>
  <div class="init-container">
    <div class="mask-container" v-if="isMask"></div>
    <div class="container">
      <Split v-model="splitLeft">
        <template #left>
          <o-tree-grid :config="treeConfig"></o-tree-grid>
        </template>
        <template #right>
          <Split v-model="splitTop" mode="vertical">
            <template #top>
              <div class="group-container">
                <div class="slot-container">
                  <div
                    v-for="(group, type) in groupedData"
                    :key="type"
                    class="slot-group"
                  >
                    <div class="group-title">
                      {{ getClassificationName(type) }}
                    </div>
                    <div class="card-container">
                      <Card
                        v-for="(item, index) in group"
                        :key="index"
                        class="control-card"
                      >
                        <div slot="title">
                          {{ item.pId }} - {{ item.equipName }}
                        </div>
                        <div class="card-content">
                          <div
                            class="mode-switch"
                            v-if="
                              item.classification !== 5 &&
                                item.classification !== 6 &&
                                item.classification !== 8
                            "
                          >
                            <RadioGroup
                              v-model="item.isAuto.value"
                              type="button"
                              button-style="solid"
                              @on-change="changeMode(item)"
                            >
                              <Radio
                                :label="getAutoValue(item.classification, 1)"
                              >
                                <span>{{
                                  getAutoTitle(item.classification, 1)
                                }}</span>
                              </Radio>
                              <Radio
                                :label="getAutoValue(item.classification, 0)"
                              >
                                <span>{{
                                  getAutoTitle(item.classification, 0)
                                }}</span>
                              </Radio>
                            </RadioGroup>
                          </div>
                          <Button
                            :disabled="getDisabled(item)"
                            :type="getBtnType(item)"
                            @click="toggleStatus(item)"
                          >
                            {{ getSwitchVal(item) }}
                          </Button>
                        </div>
                      </Card>
                    </div>
                  </div>
                </div>
              </div>
            </template>
            <template #bottom>
              <div class="non-tank-container">
                <Split v-model="splitNonTank" class="non-tank-split">
                  <template #left>
                    <div class="left-panel">
                      <div class="section">
                        <h3>门盖控制</h3>
                        <div class="control-group">
                          <Button
                            :type="
                              nonTankConfig.doorCover.allowIndividualControl
                                .value
                                ? 'success'
                                : 'error'
                            "
                            @click="toggleDoor('allowIndividualControl')"
                          >
                            {{
                              nonTankConfig.doorCover.allowIndividualControl
                                .value
                                ? '门盖允许单独全开关'
                                : '门盖禁止单独全开关'
                            }}
                          </Button>
                          <Button
                            :disabled="
                              !nonTankConfig.doorCover.allowIndividualControl
                                .value
                            "
                            type="primary"
                            @click="toggleDoor('allOpen')"
                          >
                            一键全开
                          </Button>
                          <Button
                            :disabled="
                              !nonTankConfig.doorCover.allowIndividualControl
                                .value
                            "
                            type="error"
                            @click="toggleDoor('allClose')"
                          >
                            一键全关
                          </Button>
                        </div>
                      </div>

                      <div class="section">
                        <h3>泵控制</h3>
                        <div class="control-group">
                          <Button
                            v-for="(pump, key) in nonTankConfig.pumps"
                            :key="key"
                            :type="pump.value ? 'success' : 'error'"
                            @click="togglePump(key)"
                          >
                            {{ getPumpName(key) }}:
                            {{ pump.value ? '开' : '关' }}
                          </Button>
                        </div>
                      </div>
                      <div class="footer-info">
                        <div class="footer-left">
                          <div class="title">阳极移动</div>
                          <RadioGroup
                            v-model="
                              nonTankConfig.slotEdgeTransmission.isAuto.value
                            "
                            type="button"
                            button-style="solid"
                            @on-change="
                              changeMode(nonTankConfig.slotEdgeTransmission)
                            "
                          >
                            <Radio label="true">
                              <span>自动</span>
                            </Radio>
                            <Radio label="false">
                              <span>手动</span>
                            </Radio>
                          </RadioGroup>
                          <Button
                            :disabled="
                              nonTankConfig.slotEdgeTransmission.isAuto
                                .value === 'true'
                            "
                            :type="
                              nonTankConfig.slotEdgeTransmission.isRunning.value
                                ? 'success'
                                : 'error'
                            "
                            @click="
                              changeStatus(
                                nonTankConfig.slotEdgeTransmission.isRunning
                              )
                            "
                          >
                            {{
                              nonTankConfig.slotEdgeTransmission.isRunning.value
                                ? '开'
                                : '关'
                            }}
                          </Button>
                        </div>
                        <Form :label-width="100">
                          <FormItem label="车暂停位">
                            <InputNumber
                              v-model="nonTankConfig.carStop.stopStation.value"
                              @on-blur="
                                handleBlur(nonTankConfig.carStop.stopStation)
                              "
                            />
                          </FormItem>
                          <FormItem label="车暂停时">
                            <InputNumber
                              v-model="nonTankConfig.carStop.stopTime.value"
                              @on-blur="
                                handleBlur(nonTankConfig.carStop.stopTime)
                              "
                            />
                          </FormItem>
                        </Form>
                      </div>
                    </div>
                  </template>
                  <template #right>
                    <div class="right-panel">
                      <div class="section">
                        <h3>吹干槽26控制</h3>
                        <div class="fan-control">
                          <div class="control-group">
                            <Button
                              :type="
                                nonTankConfig.dryingTank26.solenoidValve.value
                                  ? 'success'
                                  : 'error'
                              "
                              @click="toggleDryingTank('solenoidValve')"
                            >
                              {{
                                nonTankConfig.dryingTank26.solenoidValve.value
                                  ? '电磁阀开'
                                  : '电磁阀关'
                              }}
                            </Button>
                            <div>
                              <InputNumber
                                v-model="
                                  nonTankConfig.dryingTank26.windCutDelay.value
                                "
                                @on-change="changeDryingTankDelay"
                              ></InputNumber>
                              <span>秒风切延迟</span>
                            </div>
                          </div>
                          <div class="control-group" style="margin-top: 10px;">
                            <Button
                              :type="
                                nonTankConfig.dryingTank26.rightLimit.value
                                  ? 'success'
                                  : 'error'
                              "
                              @click="toggleDryingTank('rightLimit')"
                            >
                              右限位:
                              {{
                                nonTankConfig.dryingTank26.rightLimit.value
                                  ? '触发'
                                  : '未触发'
                              }}
                            </Button>
                            <Button
                              :type="
                                nonTankConfig.dryingTank26.leftLimit.value
                                  ? 'success'
                                  : 'error'
                              "
                              @click="toggleDryingTank('leftLimit')"
                            >
                              左限位:
                              {{
                                nonTankConfig.dryingTank26.leftLimit.value
                                  ? '触发'
                                  : '未触发'
                              }}
                            </Button>
                          </div>
                          <div class="control-group" style="margin-top: 10px;">
                            <Button
                              :type="
                                nonTankConfig.dryingTank26.start.value
                                  ? 'success'
                                  : 'error'
                              "
                              @click="controlBtn('start')"
                            >
                              {{
                                nonTankConfig.dryingTank26.start.value
                                  ? '已启动'
                                  : '未启动'
                              }}
                            </Button>
                            <Button
                              :type="
                                nonTankConfig.dryingTank26.stop.value
                                  ? 'success'
                                  : 'error'
                              "
                              @click="controlBtn('stop')"
                            >
                              {{
                                nonTankConfig.dryingTank26.stop.value
                                  ? '已停止'
                                  : '未停止'
                              }}
                            </Button>
                          </div>
                          <div class="control-group" style="margin-top: 10px;">
                            <div
                              class="btn-status"
                              :class="{
                                active:
                                  nonTankConfig.dryingTank26.status.manualMode
                                    .value
                              }"
                            >
                              手动模式
                            </div>
                            <div
                              class="btn-status"
                              :class="{
                                active:
                                  nonTankConfig.dryingTank26.status.ready.value
                              }"
                            >
                              准备就绪
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </template>
                </Split>
              </div>
            </template>
          </Split>
        </template>
      </Split>
    </div>
  </div>
</template>

<script lang="ts">
import {
  Tsrv,
  T_srv,
  ifs,
  ts,
  vue,
  I_cmd,
  T_cmd,
  treeConfig,
  rowData,
  configData,
  N_SlotBodySet,
  nonTankConfigData
} from './config';

@T_srv.comp
export default class cSlotBodySet extends vue {
  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  /* 组件名 */
  private name: string = 'cSlotBodySet';

  private funName: string = '';

  private G_compName: string = this.name;

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  /* 指挥部 */
  private GT_command: I_cmd = new T_cmd();

  /* 遮罩 */
  public isMask: boolean = false;

  private splitLeft: number = 0.15;

  private splitTop: number = 0.6;

  private splitNonTank: number = 0.5;

  private codes: string[] = [];

  private treeConfig = treeConfig();

  private rowData = rowData();

  private configData = configData();

  private nonTankConfig = nonTankConfigData();

  private activeGroups: string[] = [];

  private get groupedData() {
    return this.configData.reduce((acc: Record<string, any[]>, item) => {
      const type = item.classification.toString();
      if (!acc[type]) {
        acc[type] = [];
      }
      acc[type].push(item);
      return acc;
    }, {});
  }

  private getAutoValue(num: number, type: number): string {
    let str = '';
    if (type === 1) {
      if (num === 1 || num === 2 || num === 4 || num === 9) {
        str = 'false';
      } else {
        str = 'true';
      }
    } else {
      if (num === 1 || num === 2 || num === 4 || num === 9) {
        str = 'true';
      } else {
        str = 'false';
      }
    }
    return str;
  }

  private getAutoTitle(num: number, type: number): string {
    let str = '';
    if (type === 1) {
      str = num === 3 ? '准备好' : '自动';
    } else {
      str = num === 3 ? '未准备' : '手动';
    }
    return str;
  }

  private getDisabled(item: N_SlotBodySet.configData): boolean {
    let flag = true;
    const num = item.classification;
    if (num !== 5 && num !== 6 && num !== 8) {
      if (num === 1 || num === 2 || num === 4 || num === 9 || num === 3) {
        flag = item.isAuto.value === 'false';
      } else {
        flag = item.isAuto.value === 'true';
      }
    } else {
      flag = false;
    }
    return flag;
  }

  private getSwitchVal(item: N_SlotBodySet.configData): string {
    let str = '';
    const num = item.classification;
    if (num === 6) {
      str = item.isRunning.value ? '开' : '关';
    } else if (num === 5 || num === 8) {
      str = item.isRunning.value ? '关' : '开';
    } else {
      str = item.isRunning.value ? '运行中' : '已停止';
    }
    return str;
  }

  private getBtnType(item: N_SlotBodySet.configData): string {
    let str = '';
    const num = item.classification;
    if (num === 5 || num === 8) {
      str = item.isRunning.value ? 'error' : 'success';
    } else {
      str = item.isRunning.value ? 'success' : 'error';
    }
    return str;
  }

  private getClassificationName(type: string): string {
    const map: Record<string, string> = {
      '1': '空气搅拌控制',
      '2': '喷淋控制',
      '3': '排污控制',
      '4': '槽边传动',
      '5': '槽体开关',
      '6': '过滤机开关',
      '7': '超声波开关',
      '8': '烘箱气缸',
      '9': '烘箱风机'
    };
    return map[type] || type;
  }

  created() {
    // 如果父组件没有传参，那就产生一个
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    this.GT_command.init(this, this.GT_compBoxInfo);
    this.init();
  }

  mounted() {
    /* 向父组件发送实例 */
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    this.$bus.$on(
      this.treeConfig.messageConfig.emitActions.search[0].toID,
      (msg: any) => {
        this.handleListener(msg);
      }
    );
  }

  destroyed() {
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }

    // 销毁监听事件
    this.$bus.$off(this.treeConfig.messageConfig.emitActions.search[0].toID);
  }

  private handleListener(msg: any) {
    const filter = {
      p_id: { $in: msg.content.val.filter(it => it !== null && it !== -1) }
    };
    this.GT_command.doLoadData('tank_equip_config', filter).then(
      ([b, res, rows, m]) => {
        if (!b) {
          this.$msg(msg);
          return;
        }
        this.configData = rows.map((row: N_SlotBodySet.rowData) => ({
          equipName: row.equip_name,
          classification: row.classification,
          isAuto: {
            code: row['m2o|_da_ecbox_id|_da_ecbox_det|f_code'],
            value: 'true'
          },
          isRunning: {
            code: row['m2o|attribute_id|_da_ecbox_det|f_code'],
            value: true
          },
          pId: row['m2o|p_id|tank_equip_config|equip_name']
        }));

        // 根据code读取实际值
        const codes = [];
        this.configData.forEach(item => {
          if (
            item.classification !== 5 &&
            item.classification !== 6 &&
            item.classification !== 8
          )
            codes.push(item.isAuto.code);

          codes.push(item.isRunning.code);
        });
        Tsrv.readPlcData(codes).then(r => {
          if (typeof r === 'boolean') return;

          this.configData.forEach(item => {
            if (
              item.classification !== 5 &&
              item.classification !== 6 &&
              item.classification !== 8
            )
              item.isAuto.value = r[item.isAuto.code].v.toString();
            item.isRunning.value = r[item.isRunning.code].v;
          });
          // 更新非槽体设备状态
          this.updateStatus();
        });
      }
    );
  }

  private init() {
    // 初始化读取非槽体设备状态
    this.codes = [];

    Object.values(this.nonTankConfig.doorCover).forEach(d => {
      this.codes.push(d.code);
    });

    Object.values(this.nonTankConfig.pumps).forEach(pump => {
      this.codes.push(pump.code);
    });

    Object.values(this.nonTankConfig.slotEdgeTransmission).forEach(it => {
      this.codes.push(it.code);
    });

    Object.values(this.nonTankConfig.carStop).forEach(it => {
      this.codes.push(it.code);
    });

    // 添加吹干槽26的状态码
    Object.keys(this.nonTankConfig.dryingTank26).forEach(key => {
      if (key === 'status') {
        this.codes.push(this.nonTankConfig.dryingTank26[key].manualMode.code);
        this.codes.push(this.nonTankConfig.dryingTank26[key].ready.code);
      } else {
        this.codes.push(this.nonTankConfig.dryingTank26[key].code);
      }
    });

    this.updateStatus();
  }

  private updateStatus() {
    Tsrv.readPlcData(this.codes).then(r => {
      if (typeof r === 'boolean') return;

      // 更新门盖状态
      Object.values(this.nonTankConfig.doorCover).forEach(d => {
        d.value = r[d.code].v;
      });

      // 更新泵状态
      Object.values(this.nonTankConfig.pumps).forEach(pump => {
        pump.value = r[pump.code].v;
      });

      // 更新阳极移动状态
      // Object.values(this.nonTankConfig.slotEdgeTransmission).forEach(it => {
      //   it.value = r[it.code].v;
      // });
      this.nonTankConfig.slotEdgeTransmission.isAuto.value = r[
        this.nonTankConfig.slotEdgeTransmission.isAuto.code
      ].v.toString();
      this.nonTankConfig.slotEdgeTransmission.isRunning.value =
        r[this.nonTankConfig.slotEdgeTransmission.isRunning.code].v;

      Object.values(this.nonTankConfig.carStop).forEach(it => {
        it.value = r[it.code].v * it.conversionRate;
      });

      // 更新吹干槽26状态
      Object.keys(this.nonTankConfig.dryingTank26).forEach(key => {
        if (key === 'status') {
          this.nonTankConfig.dryingTank26[key].manualMode.value =
            r[this.nonTankConfig.dryingTank26[key].manualMode.code].v;
          this.nonTankConfig.dryingTank26[key].ready.value =
            r[this.nonTankConfig.dryingTank26[key].ready.code].v;
        } else if (key === 'windCutDelay') {
          this.nonTankConfig.dryingTank26[key].value =
            r[this.nonTankConfig.dryingTank26[key].code].v *
            this.nonTankConfig.dryingTank26[key].conversionRate;
        } else {
          this.nonTankConfig.dryingTank26[key].value =
            r[this.nonTankConfig.dryingTank26[key].code].v;
        }
      });
    });
  }

  private changeDryingTankDelay() {
    const code = this.nonTankConfig.dryingTank26.windCutDelay.code;
    const value = (
      (this.nonTankConfig.dryingTank26.windCutDelay.value as number) /
      this.nonTankConfig.dryingTank26.windCutDelay.conversionRate
    ).toString();
    const data = [{ ecDetCode: code, value }];
    Tsrv.writePlcData(data).then(_ => {
      Tsrv.readPlcData([code]).then(r => {
        if (typeof r === 'boolean') return;
        this.nonTankConfig.dryingTank26.windCutDelay.value =
          r[code].v *
          this.nonTankConfig.dryingTank26.windCutDelay.conversionRate;
      });
    });
  }

  /* 切换设备状态 */
  private toggleStatus(item: N_SlotBodySet.configData) {
    if (
      item.classification !== 5 &&
      item.classification !== 6 &&
      item.classification !== 8 &&
      item.isAuto.value === 'true'
    ) {
      return;
    }
    const data = [
      {
        ecDetCode: item.isRunning.code,
        value: (!item.isRunning.value).toString()
      }
    ];
    Tsrv.writePlcData(data).then(_ => {
      Tsrv.readPlcData([item.isRunning.code]).then(r => {
        if (typeof r === 'boolean') return;
        item.isRunning.value = r[item.isRunning.code].v;
      });
    });
  }

  private changeStatus(item: any) {
    const data = [
      {
        ecDetCode: item.code,
        value: (!item.value).toString()
      }
    ];

    Tsrv.writePlcData(data).then(_ => {
      Tsrv.readPlcData([item.code]).then(r => {
        if (typeof r === 'boolean') return;
        item.value = r[item.code].v;
      });
    });
  }

  private changeMode(item: N_SlotBodySet.configData) {
    const data = [
      { ecDetCode: item.isAuto.code, value: item.isAuto.value.toString() }
    ];

    Tsrv.writePlcData(data).then(_ => {
      Tsrv.readPlcData([item.isAuto.code]).then(r => {
        if (typeof r === 'boolean') return;
        item.isAuto.value = r[item.isAuto.code].v.toString();
      });
    });
  }

  private handleBlur(item: N_SlotBodySet.setInfo) {
    const data = [
      {
        ecDetCode: item.code,
        value: ((item.value as number) / item.conversionRate).toString()
      }
    ];

    Tsrv.writePlcData(data).then(_ => {
      Tsrv.readPlcData([item.code]).then(r => {
        if (typeof r === 'boolean') return;
        item.value = r[item.code].v * item.conversionRate;
      });
    });
  }

  /* 设置组件整体遮罩 */
  public setMask(p: boolean) {
    this.isMask = p;
  }

  public getMask(p: boolean): boolean {
    return this.isMask;
  }

  private getPumpName(key: string): string {
    const map = {
      oilWaterSeparator: '油水分离泵',
      chemicalDeoilingMixer: '化学除油搅拌',
      chromeAdditiveMixer: '铬酸加药搅拌'
    };
    return map[key] || key;
  }

  private toggleDoor(
    action: 'allOpen' | 'allClose' | 'allowIndividualControl'
  ) {
    const code = this.nonTankConfig.doorCover[action].code;
    const value = !this.nonTankConfig.doorCover[action].value;

    Tsrv.writePlcData([{ ecDetCode: code, value: value.toString() }]).then(
      success => {
        if (success) {
          this.nonTankConfig.doorCover[action].value = value;
          let text = '';
          if (action === 'allOpen') {
            text = '一键开启门盖成功';
          } else if (action === 'allClose') {
            text = '一键关闭门盖成功';
          }
          this.$Message.success(text);
        }
      }
    );
  }

  private togglePump(key: string) {
    const pump = this.nonTankConfig.pumps[key];
    const value = !pump.value;

    Tsrv.writePlcData([{ ecDetCode: pump.code, value: value.toString() }]).then(
      success => {
        if (success) {
          pump.value = value;
        }
      }
    );
  }

  private toggleDryingTank(type: 'windCutDelay' | 'rightLimit' | 'leftLimit') {
    const data = [
      {
        ecDetCode: this.nonTankConfig.dryingTank26[type].code,
        value: (!this.nonTankConfig.dryingTank26[type].value).toString()
      }
    ];
    Tsrv.writePlcData(data).then(success => {
      Tsrv.readPlcData([this.nonTankConfig.dryingTank26[type].code]).then(r => {
        if (typeof r === 'boolean') return;
        this.nonTankConfig.dryingTank26[type].value =
          r[this.nonTankConfig.dryingTank26[type].code].v;
      });
    });
  }

  private controlBtn(type: 'start' | 'stop') {
    const data = [
      {
        ecDetCode: this.nonTankConfig.dryingTank26[type].code,
        value: 'true'
      }
    ];
    Tsrv.writePlcData(data).then(success => {
      Tsrv.readPlcData([this.nonTankConfig.dryingTank26[type].code]).then(r => {
        if (typeof r === 'boolean') return;
        this.nonTankConfig.dryingTank26[type].value =
          r[this.nonTankConfig.dryingTank26[type].code].v;
      });
    });
  }
}
</script>
<style lang="scss" scoped>
.non-tank-container {
  padding: 15px;
  height: 100%;
  background: #f8f8f8;
  border-radius: 4px;

  .non-tank-split {
    height: 100%;
    display: flex;

    .left-panel,
    .right-panel {
      height: 100%;
      overflow-y: auto;
      padding: 0 10px;
    }
  }

  .section {
    margin-bottom: 10px;
    padding: 6px;
    background: white;
    border-radius: 4px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);

    h3 {
      margin-bottom: 6px;
      color: #17233d;
      font-size: 14px;
      font-weight: 500;
      display: flex;
      align-items: center;

      &::before {
        content: '';
        display: inline-block;
        width: 4px;
        height: 14px;
        background: #2d8cf0;
        margin-right: 8px;
        border-radius: 2px;
      }
    }

    h4 {
      margin: 4px 0;
      color: #515a6e;
      font-size: 14px;
    }
  }

  .footer-info {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    .footer-left {
      display: flex;
      flex-direction: column;
      .title {
        flex: 1;
        line-height: 36px;
      }
    }
  }

  .control-group {
    display: flex;
    gap: 12px;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;

    .ivu-btn {
      min-width: 80px;
      transition: all 0.2s;

      &:hover {
        transform: translateY(-2px);
      }
    }

    .ivu-radio-group {
      background: #f8f8f8;
      padding: 4px;
      border-radius: 4px;
    }

    .btn-status {
      width: 100px;
      height: 30px;
      display: flex;
      justify-content: center;
      align-items: center;
      border: #e8e8e8 1px solid;
      border-radius: 5px;
      background-color: #fff;
      color: #515a6e;
    }
    .active {
      background-color: #2d8cf0;
      color: #fff;
    }
  }

  .fan-control {
    margin-bottom: 15px;
    padding: 12px;
    background: #fafafa;
    border-radius: 4px;
  }
}

.container {
  height: 100%;
}
.group-container {
  height: 100%;
}

.slot-container {
  display: flex;
  flex-direction: column;
  gap: 25px;
  padding: 15px;
  overflow-y: auto;
  // max-height: calc(100vh - 100px);
  max-height: 100%;

  .group-title {
    font-size: 18px;
    font-weight: bold;
    color: #17233d;
    padding-bottom: 8px;
    border-bottom: 1px solid #e8e8e8;
    position: sticky;
    top: 0;
    background: white;
    z-index: 1;
  }

  .card-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 15px;
    margin-top: 10px;
    margin-bottom: 20px;
  }

  .mode-switch {
    margin-bottom: 10px;
  }

  .control-card {
    transition: all 0.3s;
    min-height: 120px;
    border-radius: 4px;
    overflow: hidden;

    .ivu-card-head {
      background: #f8f8f8;
      border-bottom: 1px solid #e8e8e8;
    }

    &:hover {
      box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.1);
      transform: translateY(-2px);
    }

    .ivu-btn {
      min-width: 100px;
      height: 36px;
      font-size: 14px;
    }
  }

  .status-indicator {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 6px;

    &.running {
      background: #19be6b;
    }

    &.stopped {
      background: #ed4014;
    }
  }
}
</style>
